package br.ufrj.dcc.tp.servidor.gui;

import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

import br.ufrj.dcc.tp.servidor.controller.TextAreaKeyListener;
import br.ufrj.dcc.tp.servidor.gui.event.MessageEvent;
import br.ufrj.dcc.tp.servidor.gui.event.MessageEvent.EventType;
import br.ufrj.dcc.tp.servidor.interfaces.ILogStream;
import br.ufrj.dcc.tp.servidor.interfaces.IServerController;

public class Window extends JFrame implements ILogStream {
	
	private static final long serialVersionUID = 1L;
	
	/** Historico das mensagens. */
	private JTextArea msgHistory;
	private JTextArea msgSend;
	private IServerController controller;
	
	public Window(IServerController controller){
		super("Servidor - Bate-papo TP");
		
		this.controller = controller;
		msgHistory = new JTextArea();
		msgSend = new JTextArea();
		GridBagConstraints gc = new GridBagConstraints();
		JScrollPane panel = new JScrollPane(msgHistory);
		JScrollPane panelSend = new JScrollPane(msgSend);
		Container cont = this.getContentPane();
		
		msgHistory.setEditable(false);
		msgHistory.setLineWrap(true);
		msgSend.addKeyListener(new TextAreaKeyListener(this));
		
		cont.setLayout(new GridBagLayout());
		
		// Fazer com que o ScrollPane ocupe todo o espaco disponivel
		gc.fill = GridBagConstraints.BOTH;
		gc.gridx = 0;
		gc.gridy = 0;
		gc.weightx = 3;
		gc.weighty = 5;
		gc.gridwidth = 1;
		gc.gridheight = 1;
		
		cont.add(panel, gc);
		
		gc.gridx = 0;
		gc.gridy = 1;
		gc.weightx = 3;
		gc.weighty = 1;
		gc.gridwidth = 1;
		gc.gridheight = 1;
		
		cont.add(panelSend, gc);
		
		setSize(640, 480);
		setLocationRelativeTo(null);
		setVisible(true);
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	}
	
	public void delegateSendMessage() {
		controller.sendMessage(msgSend.getText());
		// Nunca é bom deixar outra thread atualizar a GUI.
		SwingUtilities.invokeLater(new MessageEvent(msgSend, EventType.CLEAR));
	}
	
	public void appendLog(String log){
		SwingUtilities.invokeLater(new MessageEvent(msgHistory, log, EventType.APPEND));
	}
	
	@Override
	public void dispose() {
		int response = JOptionPane.YES_OPTION;
		if(controller.hasActiveClients()) {
			response = JOptionPane.showConfirmDialog(null ,"Existem clientes ativos! Tem certeza que deseja encerrar o servidor?", "Saída",JOptionPane.YES_NO_OPTION);
		}
		if(response == JOptionPane.YES_OPTION) {
			// Finaliza o servidor
			silentDispose();
			controller.shutdown();
		}
	}
	
	public void silentDispose() {
		super.dispose();
	}

	@Override
	public void flushLog() throws Exception {
		// DO NOTHING
	}

	@Override
	public void log(String s) throws Exception {
		appendLog(s);
	}
}
